﻿using System;
using System.Collections.Generic;

using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Xml;
using System.Globalization;

namespace SceneEngine
{
    public static class EngineGlobals
    {
        public static Scene Scene;
        public static ICamera Camera;

        public static ResourceContentManager TerrainContent;
        public static ContentManager Content;
        public static SpriteBatch SpriteBatch;

        public static RenderManager RenderManager;

        public static GraphicsDevice GraphicsDevice;

        public static Ray GetMouseRay()
        {
            int mouseX = Mouse.GetState().X;
            int mouseY = Mouse.GetState().Y;

            Vector2 position = new Vector2(mouseX, mouseY);

            Vector3 near = new Vector3(position, 0f);
            Vector3 far = new Vector3(position, 1f);

            Matrix translation = Matrix.CreateTranslation(Vector3.Zero);

            near = EngineGlobals.GraphicsDevice.Viewport.Unproject(near, Camera.Projection, Camera.View, translation);
            far = EngineGlobals.GraphicsDevice.Viewport.Unproject(far, Camera.Projection, Camera.View, translation);

            Ray pickRay = new Ray(near, Vector3.Normalize(far - near));

            return pickRay;
        }

        public const float DegreesToRadians = MathHelper.Pi / 180.0f;

        public static float WrapAngle(float angle)
        {
            angle = (float)Math.IEEERemainder((double)angle, 360);
            if (angle <= -180)
            {
                angle += 360;
                return angle;
            }
            if (angle > 180)
            {
                angle -= 360;
            }
            return angle;
        }

        public static void Initialize(Game game)
        {
            EngineGlobals.GraphicsDevice = game.GraphicsDevice;
            EngineGlobals.SpriteBatch = new SpriteBatch(GraphicsDevice);

            EngineGlobals.Content = game.Content;

            EngineGlobals.TerrainContent = new ResourceContentManager(game.Services, TerrainResources.ResourceManager);

            RenderManager = new RenderManager();
            DebugShapeRenderer.Initialize(game.GraphicsDevice);
        } 

        public static void Initialize(IServiceProvider serviceProvider, GraphicsDevice GraphicsDevice)
        {
            EngineGlobals.GraphicsDevice = GraphicsDevice;
            EngineGlobals.SpriteBatch = new SpriteBatch(GraphicsDevice);

            EngineGlobals.TerrainContent = new ResourceContentManager(serviceProvider, TerrainResources.ResourceManager);

            RenderManager = new RenderManager();
            DebugShapeRenderer.Initialize(GraphicsDevice);
        }

        public static Vector3 ParseVector3(string value)
        {
            string[] attributeSplit = value.Split();
            
            Vector3 parsedVector = new Vector3(float.Parse(attributeSplit[0], CultureInfo.InvariantCulture),
                                               float.Parse(attributeSplit[1], CultureInfo.InvariantCulture),
                                               float.Parse(attributeSplit[2], CultureInfo.InvariantCulture));

            return parsedVector;
        }
        public static Quaternion ParseQuaternion(string value)
        {
            string[] attributeSplit = value.Split();

            Quaternion parsedVector = new Quaternion(float.Parse(attributeSplit[0], CultureInfo.InvariantCulture),
                                                     float.Parse(attributeSplit[1], CultureInfo.InvariantCulture),
                                                     float.Parse(attributeSplit[2], CultureInfo.InvariantCulture),
                                                     float.Parse(attributeSplit[3], CultureInfo.InvariantCulture));

            return parsedVector;
        }
    }
}
